/**
 * 
 */
package ac.technion.StreamMania;

import java.util.ArrayList;
import java.util.List;

import ac.technion.StreamMania.R;
import android.content.Context;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Pair;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.CompoundButton.OnCheckedChangeListener;

/**
 * @author advinsky
 * 
 * This file handles the first screen of the application (configuration screen), 
 * where the user chooses the configurations (broadcast IP, etc.)
 * 
 */
class ConfigurationScreenManager
{
	private static final int	DEFAULT_ADDRESS_LENGTH	= 3;
	private final View m_view;
	private final List<String> m_lstOwnIpAddresses;
	private final Context m_context;
	
	private BroadcastAddressList m_broadcastAddressList;
	
	public ConfigurationScreenManager(View configurationView, List<String> ownIPAddresses, Context context)
	{
		m_view = configurationView;
		m_lstOwnIpAddresses = ownIPAddresses;
		m_context = context;
	}
	
	public void init()
	{
		initBroadcastAddressButtons();	//Top screen: Choice between 1\2\3 byte netmask and list of broadcast IP's
		initNameTextAndStartButton();	//Bottom screen: User's name field + start button.
	}
	
	/* Returns the broadcast address that the user has chosen from the list */
	public String getBroadcastAddress()
	{
		return m_broadcastAddressList.getSelectedBroadcastAddress();
	}
	
	/* Returns the user's name that he typed in */
	public String getName()
	{
		return ((EditText)m_view.findViewById(R.id.nickNameText)).getText().toString();
	}

	/* Top screen initialization: Choice between 1\2\3 byte netmask and list of broadcast IP's */
	private void initBroadcastAddressButtons()
	{
		RadioGroup broadcastGroup = (RadioGroup)m_view.findViewById(R.id.broadcastAddressGroup);
		m_broadcastAddressList = fillBroadcastAddresses(m_lstOwnIpAddresses, broadcastGroup);
		
		RadioButton oneByteNetmask = (RadioButton)m_view.findViewById(R.id.oneByteNetmask);
		RadioButton twoByteNetmask = (RadioButton)m_view.findViewById(R.id.twoByteNetmask);
		RadioButton threeByteNetmask = (RadioButton)m_view.findViewById(R.id.threeByteNetmask);
		oneByteNetmask.setOnCheckedChangeListener(new OnCheckedChangeListener()
		{
			public void onCheckedChanged(CompoundButton paramCompoundButton, boolean checked)
			{
				if (checked)
					m_broadcastAddressList.changeAddressLength(1);
			}
		});
		twoByteNetmask.setOnCheckedChangeListener(new OnCheckedChangeListener()
		{
			public void onCheckedChanged(CompoundButton paramCompoundButton, boolean checked)
			{
				if (checked)
					m_broadcastAddressList.changeAddressLength(2);
			}
		});
		threeByteNetmask.setOnCheckedChangeListener(new OnCheckedChangeListener()
		{
			public void onCheckedChanged(CompoundButton paramCompoundButton, boolean checked)
			{
				if (checked)
					m_broadcastAddressList.changeAddressLength(3);
			}
		});
	}
	
	/* Bottom screen initialization: User's name field + start button. */
	private void initNameTextAndStartButton()
	{
		final Button sender = (Button)m_view.findViewById(R.id.sender);
		final Button receiver = (Button)m_view.findViewById(R.id.receiver);
		final EditText nicknameText = (EditText)m_view.findViewById(R.id.nickNameText);
		nicknameText.addTextChangedListener(new TextWatcher()
			{
				public void onTextChanged(CharSequence s, int start, int before, int count)
				{
					sender.setEnabled(nicknameText.getText().length() > 0);
					receiver.setEnabled(nicknameText.getText().length() > 0);
				}
				
				public void beforeTextChanged(CharSequence s, int start, int count, int after)
				{
				}
				
				public void afterTextChanged(Editable s)
				{
				}
			});
	}
	
	/* Fills the list of address user can choose to broadcast on */
	private BroadcastAddressList fillBroadcastAddresses(List<String> ipAddresses, RadioGroup broadcastGroup)
	{
		BroadcastAddressList broadcastAddressList = new BroadcastAddressList(broadcastGroup);
		for (String ipAddress : ipAddresses)
			broadcastAddressList.addAddress(ipAddress, DEFAULT_ADDRESS_LENGTH);

		return broadcastAddressList;
	}
	
	/* The private class handles the list of broadcast address that the user can choose from */
	private class BroadcastAddressList
	{
		private final RadioGroup m_radioGroup;
		private final List<Pair<RadioButton, String>> m_lstButtons = new ArrayList<Pair<RadioButton, String>>();
		
		public BroadcastAddressList(RadioGroup radioGroup)
		{
			m_radioGroup = radioGroup;
		}
		
		public void addAddress(String address, int addressLength)
		{
			RadioButton button = new RadioButton(m_context);
			button.setText(buildBroadcastAddres(address, addressLength));
			
			button.setTypeface(null,Typeface.BOLD);
			
			button.setLayoutParams(new RadioGroup.LayoutParams(LayoutParams.FILL_PARENT,ViewGroup.LayoutParams.FILL_PARENT));
			button.setGravity(Gravity.CENTER_HORIZONTAL);
			m_radioGroup.addView(button);
			if (m_radioGroup.getChildCount() == 1)
				button.setChecked(true);
			
			m_lstButtons.add(new Pair<RadioButton, String>(button, address));
		}
		
		public void changeAddressLength(int newAddressLength)
		{
			for (Pair<RadioButton, String> addrPair : m_lstButtons)
			{
				addrPair.first.setText(buildBroadcastAddres(addrPair.second, newAddressLength));
			}
		}
		
		public String getSelectedBroadcastAddress()
		{
			int buttonId = m_radioGroup.getCheckedRadioButtonId();
			for (Pair<RadioButton, String> addrPair : m_lstButtons)
			{
				if (addrPair.first.getId() == buttonId)
					return addrPair.first.getText().toString();
			}
			
			return null;
		}

		private String buildBroadcastAddres(String address, int addressLength)
		{
			String[] splitAddress = address.split("\\.");
			StringBuilder sb = new StringBuilder(splitAddress[0]);
			
			for (int i = 1; i < addressLength; i++)
			{
				sb.append(".");
				sb.append(splitAddress[i]);
			}
			
			for (int i = 0; i < 4 - addressLength; i++)
				sb.append(".255");
			
			return sb.toString();
		}
	}
}
